package com.springboot.frame.controller;

import com.springboot.frame.config.LuceneConfig;
import com.springboot.frame.model.Content;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author liheng
 * @ClassName SearchController
 * @Description
 * @date 2021-03-15 14:20
 */
@Controller
@RequestMapping("/")
public class SearchController {
    @Autowired
    private IndexWriter indexWriter;
    @Autowired
    private Analyzer smartChineseAnalyzer;
    @Autowired
    private SearcherManager searcherManager;


    @RequestMapping("search")
    public String search(@RequestParam("text") String text, HttpServletRequest request) throws IOException, ParseException, InvalidTokenOffsetsException {
        // 索引搜索工具
        searcherManager.maybeRefresh();
        IndexSearcher searcher = searcherManager.acquire();
        BooleanQuery.Builder builder = new BooleanQuery.Builder();
        // 创建查询解析器,两个参数：默认要查询的字段的名称，分词器
        builder.add(new QueryParser("descs", smartChineseAnalyzer).parse(text), BooleanClause.Occur.MUST);
        // 获取前十条记录
        TopDocs topDocs = searcher.search(builder.build(), 10);
        // 获取总条数
        System.out.println("本次搜索共找到" + topDocs.totalHits + "条数据");

        //高亮显示
        SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
        Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(builder.build()));
        //高亮后的段落范围在100字内
        Fragmenter fragmenter = new SimpleFragmenter(100);
        highlighter.setTextFragmenter(fragmenter);

        // 获取得分文档对象（ScoreDoc）数组.SocreDoc中包含：文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        List<Content> list = new ArrayList<>();
        Content content;
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            // 根据编号去找文档
            Document doc = searcher.doc(docID);
            content = new Content();
            content.setId(Integer.valueOf(doc.get("id")));
            content.setDescs( highlighter.getBestFragment(smartChineseAnalyzer,"descs",doc.get("descs")));
            content.setPrice(doc.get("price"));
            content.setTitle(doc.get("title"));
            list.add(content);
        }
        request.setAttribute("list", list);
        return "search";
    }

    @ResponseBody
    @RequestMapping("/create")
    public String createIndex() throws IOException {
        List<Content> list1 = LuceneConfig.INDEX_DATA;
        // 创建文档的集合
        Collection<Document> docs = new ArrayList<>();
        for (int i = 0; i < list1.size(); i++) {
            // 创建文档对象
            Document document1 = new Document();
            //StringField会创建索引，但是不会被分词，TextField，即创建索引又会被分词。
            document1.add(new StringField("id", list1.get(i).getId() + "", Field.Store.YES));
            document1.add(new TextField("title", list1.get(i).getTitle(), Field.Store.YES));
            document1.add(new TextField("price", list1.get(i).getPrice(), Field.Store.YES));
            document1.add(new TextField("descs", list1.get(i).getDescs(), Field.Store.YES));
            docs.add(document1);
        }
        // 把文档集合交给IndexWriter
        indexWriter.addDocuments(docs);
        // 提交
        indexWriter.commit();
        return "success";
    }
}
